/**
 * @file app_config.c
 * @brief 应用配置文件
 * @author liucx (liucx@fiberhome.com)
 * @version 1.0
 * @date 2020-12-01
 * @copyright Copyright (c) 2020  烽火通信
 ***************************************************************
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version  <th>Author  <th>Description
 * <tr><td>2020-12-01 <td>1.0      <td>liucx   <td>内容
 * </table>
 */ 
#include "project_config.h"
#if BOARD_PCU_EN
#include "app_config.h"
#include "app_control.h"
#include "bsp_rtc.h"
#include "msc.h"
#include "msc_485.h"
#include "alarm.h"
#include "bsp_log.h"
#include "common_interfaces.h"
#include "app_data.h"
#define CONFIG_CHECK_POINT(a)                                               \
    {                                                                   \
        if (NULL == a)                                                  \
        {                                                               \
            return ERROR_COM;                                               \
        }                                                               \
    }

#define CONFIG_CHECK_PARA            \
    {                            \
        CONFIG_CHECK_POINT(indata); \
        CONFIG_CHECK_POINT(outdata);  \
        CONFIG_CHECK_POINT(outdata_len);   \
    }

/**
 * @brief 漏电电流设置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_leakage_threshold_set(uint8 *src,uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t leakage_long = 0;
    uint8_t leakage_times = 0;
    uint16_t offset = 0;
    uint16_t leakage_values = 0;
    CONFIG_CHECK_PARA;
    POUT_STORE_SHORT(indata, leakage_values, offset);
    POUT_STORE_CHAR(indata,leakage_times,offset);
    POUT_STORE_CHAR(indata,leakage_long,offset);
    if(OK != app_control_leakage_threshold_set(leakage_values,leakage_times,leakage_long))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 漏电电流查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_leakage_threshold_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t leakage_long = 0;
    uint8_t leakage_times = 0;
    uint16_t offset = 0;
    uint16_t leakage_values = 0;
    CONFIG_CHECK_PARA;
    if(OK != app_control_leakage_threshold_get(&leakage_values,&leakage_times,&leakage_long))
    {
        return ERROR_COM;
    }
    PIN_STORE_SHORT(outdata,leakage_values,offset);
    PIN_STORE_CHAR(outdata,leakage_times,offset);
    PIN_STORE_CHAR(outdata,leakage_long,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 温湿度阈值配置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_temperature_threshold_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    float high_temperature = 0;
    float low_temperature = 0;
    CONFIG_CHECK_PARA;
    POUT_STORE_FLOAT(indata,high_temperature,offset);
    POUT_STORE_FLOAT(indata,low_temperature,offset);
    if(OK != app_control_temperature_threshold_set(high_temperature,low_temperature))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 温湿度阈值查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_temperature_threshold_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    float high_temperature = 0;
    float low_temperature = 0;
    float temperature;
    CONFIG_CHECK_PARA;
    if(OK != app_control_temperature_threshold_get(&high_temperature,&low_temperature))
    {
        return ERROR_COM;
    }
    PIN_STORE_FLOAT(outdata,high_temperature,offset);
    PIN_STORE_FLOAT(outdata,low_temperature,offset);
    if(OK != app_control_temperature(&temperature))
    {
        return ERROR_COM;
    }
    PIN_STORE_FLOAT(outdata,temperature,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 风扇、加热棒阈值配置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_fan_heater_threshold_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    float fan_temperature = 0;
    float heater_temperature = 0;
    CONFIG_CHECK_PARA;
    POUT_STORE_FLOAT(indata,fan_temperature,offset);
    POUT_STORE_FLOAT(indata,heater_temperature,offset);
    if(OK != app_control_fan_heater_threshold_set(fan_temperature,heater_temperature))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 风扇、加热棒阈值查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_fan_heater_threshold_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    float fan_temperature = 0;
    float heater_temperature = 0;
    CONFIG_CHECK_PARA;
    if(OK != app_control_fan_heater_threshold_get(&fan_temperature,&heater_temperature))
    {
        return ERROR_COM;
    }
    PIN_STORE_FLOAT(outdata,fan_temperature,offset);
    PIN_STORE_FLOAT(outdata,heater_temperature,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 倾斜阈值配置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_tilt_threshold_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    float angle_x;
    float angle_y;
    float angle_z;
    uint16_t offset = 0;
    TILT_TASK_t tilt_task;
    CONFIG_CHECK_PARA;
    offset+=12;
    POUT_STORE_FLOAT(indata,tilt_task.tilt,offset);
    if(OK != app_control_tilt(&angle_x, &angle_y, &angle_z))
    {
        return ERROR_COM;
    }
    tilt_task.tilt_x = angle_x;
    tilt_task.tilt_y = angle_y;
    tilt_task.tilt_z = angle_z;
    if(OK != app_control_tilt_threshold_set(tilt_task))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 倾斜阈值查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_tilt_threshold_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    TILT_TASK_t tilt_task;
    CONFIG_CHECK_PARA;
    if(OK != app_control_tilt_threshold_get(&tilt_task))
    {
        return ERROR_COM;
    }
    PIN_STORE_FLOAT(outdata,tilt_task.tilt_x,offset);
    PIN_STORE_FLOAT(outdata,tilt_task.tilt_y,offset);
    PIN_STORE_FLOAT(outdata,tilt_task.tilt_z,offset);
    PIN_STORE_FLOAT(outdata,tilt_task.tilt,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 倾斜角度查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_tilt_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    float angle_x = 0;
    float angle_y = 0;
    float angle_z = 0;
    CONFIG_CHECK_PARA;
    if(OK != app_control_tilt(&angle_x,&angle_y,&angle_z))
    {
        if(OK != Alarm_Send(ALARM_LEAN_COLLECT_FAULT,NULL,0,ALARM_ON))
        {
            log_e("ALARM_LEAN_COLLECT_FAULT ALARM_ON send fail \r\n");
        }
        return ERROR_COM;
    }
    else
    {
        if(OK != Alarm_Send(ALARM_LEAN_COLLECT_FAULT,NULL,0,ALARM_OFF))
        {
            log_e("ALARM_LEAN_COLLECT_FAULT ALARM_OFF send fail \r\n");
        }
    }
    PIN_STORE_FLOAT(outdata,angle_x,offset);
    PIN_STORE_FLOAT(outdata,angle_y,offset);
    PIN_STORE_FLOAT(outdata,angle_z,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 单灯计划删除接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_light_plan_del(uint8 *src,uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t plan_num = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    POUT_STORE_CHAR(indata,plan_num,offset);
    if(plan_num > LIGHT_PLAN_MAX_NUM + AMBIENT_PLAN_MAX_NUM || plan_num == 0)
    {
        return ERROR_COM;
    }
    if(OK != app_control_plan_del(plan_num))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 单灯计划查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_light_plan_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t i = 0;
    uint8_t item = 0;
    uint16_t offset = 0;
    PLAN_VALUES_t plan_values;
    CONFIG_CHECK_PARA;
    offset+=1;
    for( i = 0 ; i < LIGHT_PLAN_MAX_NUM ; i++)
    {
        if(OK != app_control_plan_sel(i,&plan_values))
        {
            return ERROR_COM;
        }
        if(plan_values.plan_type != PLAN_TYPE_NULL)
        {
            PIN_STORE_CHAR(outdata,i+1,offset);
            PIN_STORE_CHAR(outdata,plan_values.light_num,offset);
            PIN_STORE_CHAR(outdata,plan_values.light_values,offset);
            PIN_STORE_LONG(outdata,plan_values.work_time,offset);
            item++;
        }
    }
    PIN_CHAR(outdata,item);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 单灯计划配置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_light_plan_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    PLAN_VALUES_t plan_values;
    CONFIG_CHECK_PARA;
    POUT_STORE_CHAR(indata,plan_values.light_num,offset);
    if((plan_values.light_num > MAX_LIGHT_NUM && plan_values.light_num != BOTH_LIGHT_NUM)|| plan_values.light_num < MIN_LIGHT_NUM)
    {
        return ERROR_COM;
    }
    POUT_STORE_CHAR(indata,plan_values.light_values,offset);
    if(plan_values.light_values > MAX_LIGHT_VALUES)
    {
        return ERROR_COM;
    }
    POUT_STORE_LONG(indata,plan_values.work_time,offset);
    plan_values.plan_type = PLAN_TYPE_LIGHT;
    if(OK != app_control_plan_add(&plan_values))
    {
        return ERROR_COM;
    }
    *outdata_len = 0;
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 通道物理映射配置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_mapping_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t item = 0;
    uint8_t info_num = 0;
    uint8_t dev_type = 0;
    uint8_t i = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    POUT_STORE_CHAR(indata,item,offset);
    if(0 == item)
    {
        return ERROR_COM;
    }
    for( i = 0 ; i < item ; i++)
    {
        POUT_STORE_CHAR(indata,info_num,offset);
        POUT_STORE_CHAR(indata,dev_type,offset);
        if(OK != app_control_map_set(info_num,dev_type))
        {
            return ERROR_COM;
        }
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 通道物理映射查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_mapping_get(uint8 *src,uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t i = 1;
    uint8_t item = 0;
    uint8_t dev_type = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    offset+=1;
    for( i = 1 ; i < ALTERNATING_LOOP_LEN + DIRECT_LOOP_LEN +3 ;i++)
    {
        if(OK != app_control_map_get(i,&dev_type))
        {
            return ERROR_COM;
        }
        if(dev_type != 0)
        {
            item++;
            PIN_STORE_CHAR(outdata,i,offset);
            PIN_STORE_CHAR(outdata,dev_type,offset);
        }
    }
    PIN_CHAR(outdata,item);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 开关状态配置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_switch_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t item = 0;
    uint8_t i = 0;
    uint8_t info_num = 0;
    uint8_t switch_status = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    POUT_STORE_CHAR(indata,item,offset);
    if(item == 0)
    {   
        log_i("item check fail %d ",item);
        return ERROR_COM;
    }
    for( i = 0 ; i < item ;i++)
    {
        POUT_STORE_CHAR(indata,info_num,offset);
        if( 0 == info_num )
        {
            log_i("info_num check fail %d",info_num);
            return ERROR_COM;
        }
        POUT_STORE_CHAR(indata,switch_status,offset);
        if(OK != app_control_switch_set(info_num,switch_status))
        {
            log_i("app_control_switch_set fail ");
            return ERROR_COM;
        }
    }
    if(OK != app_control_save())
    {
        log_i("app_control_save fail ");
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 开关状态查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_switch_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t i = 1;
    uint8_t status = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    offset+=1;

    for( i = 1 ; i <= ALTERNATING_LOOP_LEN + DIRECT_LOOP_LEN + DI_LEN ; i++)
    {
        if(OK != app_control_switch_get(i,&status))
        {
            return ERROR_COM;
        }
        PIN_STORE_CHAR(outdata,i,offset);
        PIN_STORE_CHAR(outdata,status,offset);
    }
    PIN_CHAR(outdata,ALTERNATING_LOOP_LEN + DIRECT_LOOP_LEN + DI_LEN);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 单灯亮度配置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_single_light_brightness_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t light_values_1 = 0;
    uint8_t light_values_2 = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    POUT_STORE_CHAR(indata,light_values_1,offset);
    if(light_values_1 > MAX_LIGHT_VALUES)
    {
        return ERROR_COM;
    }
    POUT_STORE_CHAR(indata,light_values_2,offset);
    if(light_values_2 > MAX_LIGHT_VALUES)
    {
        return ERROR_COM;
    }
    if(OK != app_control_single_light_set(light_values_1,light_values_2))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 单灯亮度查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_single_light_brightness_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t light_values_1 = 0;
    uint8_t light_values_2 = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    if(OK != app_control_single_light_get(&light_values_1,&light_values_2))
    {
        return ERROR_COM;
    }
    PIN_STORE_CHAR(outdata,light_values_1,offset);
    PIN_STORE_CHAR(outdata,light_values_2,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 设备信息配置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_info_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    INFO_t dev_info;
    CONFIG_CHECK_PARA;
    POUT_STORE_BUFF(indata,dev_info.dev_name,offset,DEV_NAME_LEN);
    POUT_STORE_BUFF(indata,dev_info.pole_num,offset,POLE_NUM);
    POUT_STORE_BUFF(indata,dev_info.longitude,offset,LONGITUDE_LEN);
    POUT_STORE_BUFF(indata,dev_info.latitude,offset,LATITUDE_LEN);
    if(OK != app_control_dev_info_set(dev_info))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 设备信息查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_info_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{   
    uint16_t offset = 0;
    INFO_t dev_info;
    CONFIG_CHECK_PARA;
    if(OK != app_control_dev_info_get(&dev_info))
    {
        return ERROR_COM;
    }
    PIN_STORE_BUFF(outdata,dev_info.dev_name,offset,DEV_NAME_LEN);
    PIN_STORE_BUFF(outdata,dev_info.pole_num,offset,POLE_NUM);
    PIN_STORE_BUFF(outdata,dev_info.longitude,offset,LONGITUDE_LEN);
    PIN_STORE_BUFF(outdata,dev_info.latitude,offset,LATITUDE_LEN);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 设备网络信息配置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_net_set(uint8 *src,uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    uint32_t dev_ip = 0;
    uint32_t dev_mask = 0;
    uint32_t dev_gateway  = 0;
    NET_t dev_net;
    CONFIG_CHECK_PARA;
    POUT_STORE_LONG(indata,dev_ip,offset);
    POUT_STORE_LONG(indata,dev_mask,offset);
    POUT_STORE_LONG(indata,dev_gateway,offset);
    com_getip_tostring_fromlong(dev_net.ip,dev_ip);
    com_getip_tostring_fromlong(dev_net.mask,dev_mask);
    com_getip_tostring_fromlong(dev_net.gateway,dev_gateway);
    if(OK != app_control_dev_net_set(dev_net))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 设备网络信息查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_net_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t i = 0;
    uint16_t offset = 0;
    uint32_t dev_ip = 0;
    uint32_t dev_mask = 0;
    uint32_t dev_gateway  = 0;
    NET_t dev_net;
    CONFIG_CHECK_PARA;
    if(OK != app_control_dev_net_get(&dev_net))
    {
        return ERROR_COM;
    }
    for(i =0; i < NET_ARR_LEN ; i++ )
    {
        dev_ip += dev_net.ip[i] <<(8 * (NET_ARR_LEN - i - 1));
    }
    for(i =0; i < NET_ARR_LEN ; i++ )
    {
        dev_mask += dev_net.mask[i] <<(8 * (NET_ARR_LEN - i - 1));
    }
    for(i =0; i < NET_ARR_LEN ; i++ )
    {
        dev_gateway += dev_net.gateway[i] <<(8 * (NET_ARR_LEN - i - 1));
    } 
    PIN_STORE_LONG(outdata,dev_ip,offset);
    PIN_STORE_LONG(outdata,dev_mask,offset);
    PIN_STORE_LONG(outdata,dev_gateway,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 平台连接信息配置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_north_connect_set(uint8 *src,uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    uint16_t dev_connect_port = 0;
    uint32_t dev_connect_ip = 0;
    NORTH_CONNECT_t dev_north_connect;
    CONFIG_CHECK_PARA;
    POUT_STORE_LONG(indata,dev_connect_ip,offset);
    POUT_STORE_SHORT(indata,dev_connect_port,offset);
    com_getip_tostring_fromlong(dev_north_connect.ip,dev_connect_ip);
    dev_north_connect.port = dev_connect_port;
    if(OK != app_control_dev_north_connect_set(dev_north_connect))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 平台连接信息查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_north_connect_get(uint8 *src,uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t i = 0;
    uint16_t offset = 0;
    uint16_t dev_connect_port = 0;
    uint32_t dev_connect_ip = 0;
    NORTH_CONNECT_t dev_north_connect;
    CONFIG_CHECK_PARA;
    if(OK != app_control_dev_north_connect_get(&dev_north_connect))
    {
        return ERROR_COM;
    }
    for(i = 0; i < NET_ARR_LEN ;i++ )
    {
        dev_connect_ip += dev_north_connect.ip[i] <<(8 * (NET_ARR_LEN - i - 1));
    }
    dev_connect_port = dev_north_connect.port;
    PIN_STORE_LONG(outdata,dev_connect_ip,offset);
    PIN_STORE_SHORT(outdata,dev_connect_port,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 485信息配置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_485_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t i = 0;
    uint8_t item = 0;
    uint8_t com_num = 0;
    uint16_t offset = 0;
    SERIAL_485_t serial_485;
    CONFIG_CHECK_PARA;
    POUT_STORE_CHAR(indata,item,offset);
    if(item == 0)
    {
        return ERROR_COM;
    }
    for( i = 0 ; i < item ; i++)
    {
        POUT_STORE_CHAR(indata,com_num,offset);
        if(com_num > SERIAL_485_2)
        {
            return ERROR_COM;
        }
        POUT_STORE_LONG(indata,serial_485.baudrate,offset);
        POUT_STORE_CHAR(indata,serial_485.databit,offset);
        POUT_STORE_CHAR(indata,serial_485.stopbit,offset);
        POUT_STORE_CHAR(indata,serial_485.parity,offset);
        POUT_STORE_CHAR(indata,serial_485.flowctl,offset);
        if(OK != app_control_dev_485_set(com_num,serial_485))
        {
            return ERROR_COM;
        }
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;              
}

/**
 * @brief 485信息查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_485_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t i = 1;
    uint8_t item = 0;
    uint16_t offset = 0;
    SERIAL_485_t serial_485;
    CONFIG_CHECK_PARA;
    offset+=1;
    for(i = 1 ; i <= SERIAL_485_2 ;i++)
    {
        if(OK != app_control_dev_485_get(i,&serial_485))
        {
            return ERROR_COM;
        }
        item++;
        PIN_STORE_CHAR(outdata,i,offset);
        PIN_STORE_LONG(outdata,serial_485.baudrate,offset);
        PIN_STORE_CHAR(outdata,serial_485.databit,offset);
        PIN_STORE_CHAR(outdata,serial_485.stopbit,offset);
        PIN_STORE_CHAR(outdata,serial_485.parity,offset);
        PIN_STORE_CHAR(outdata,serial_485.flowctl,offset);
    }
    PIN_CHAR(outdata,item);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 心跳周期设置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_heart_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    uint16_t heart = 0;
    CONFIG_CHECK_PARA;
    POUT_STORE_SHORT(indata,heart,offset);
    if(heart < MIN_HEARTBEAT || heart > MAX_HEARTBEAT)
    {
        return ERROR_COM;
    }
    if(OK != app_control_heart_set(heart))
    {
        return ERROR_COM;
    }
    app_data_heart_set(heart);
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 心跳周期查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_heart_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    uint16_t heart = 0;
    CONFIG_CHECK_PARA;
    if(OK != app_control_heart_get(&heart))
    {
        return ERROR_COM;
    }
    PIN_STORE_SHORT(outdata,heart,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 设备版本号查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_version_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    char hard_version[VERSION_LENGTH];
    char soft_version[VERSION_LENGTH];
    memset(hard_version,0,VERSION_LENGTH);
    memset(soft_version,0,VERSION_LENGTH);
    snprintf(hard_version,20,PCU_HW_VERSION);
    snprintf(soft_version,20,PCU_SW_VERSION);
    PIN_STORE_BUFF(outdata,hard_version,offset,VERSION_LENGTH);
    PIN_STORE_BUFF(outdata,soft_version,offset,VERSION_LENGTH);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 高低温、漏电告警动作使能设置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_temperature_leakage_enable_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t temperature_action_flag = 0;
    uint8_t leakage_action_flag = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    POUT_STORE_CHAR(indata,temperature_action_flag,offset);
    POUT_STORE_CHAR(indata,leakage_action_flag,offset);
    if(OK != app_control_temperature_leakage_set(temperature_action_flag,leakage_action_flag))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 高低温、漏电告警动作使能获取接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_temperature_leakage_enable_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t temperature_action_flag = 0;
    uint8_t leakage_action_flag = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    if(OK != app_control_temperature_leakage_get(&temperature_action_flag,&leakage_action_flag))
    {
        return ERROR_COM;
    }
    PIN_STORE_CHAR(outdata,temperature_action_flag,offset);
    PIN_STORE_CHAR(outdata,leakage_action_flag,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief DI设备初始状态设置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_di_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t DI1_flag = 0;
    uint8_t DI2_flag = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    POUT_STORE_CHAR(indata,DI1_flag,offset);
    POUT_STORE_CHAR(indata,DI2_flag,offset);
    if(OK != app_control_DI_flag_set(DI1_flag,DI2_flag))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief DI设备初始状态获取接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_di_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{   
    uint8_t DI1_flag = 0;
    uint8_t DI2_flag = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    if(OK != app_control_DI_flag_get(&DI1_flag,&DI2_flag))
    {   
        return ERROR_COM;
    }
    PIN_STORE_CHAR(outdata,DI1_flag,offset);
    PIN_STORE_CHAR(outdata,DI2_flag,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 氛围灯配置接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_ambient_set(uint8 *src,uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t ambient_mode = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    POUT_STORE_CHAR(indata,ambient_mode,offset);
    if(OK != app_control_ambient_set(ambient_mode))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 氛围灯查询接口回调
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_ambient_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t ambient_mode = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    if(OK != app_control_ambient_get(&ambient_mode))
    {
        return ERROR_COM;
    }
    PIN_STORE_CHAR(outdata,ambient_mode,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 时钟配置接口
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_clock_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    uint32_t clock_time;
    rtc_time_t rtc_time;
    CONFIG_CHECK_PARA;
    POUT_STORE_LONG(indata,clock_time,offset);
    clock_time+=8*60*60;
    extern void to_tm( uint32_t tim, rtc_time_t * tm );
    to_tm(clock_time,&rtc_time);
    if(OK != RtcSet(&rtc_time))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 通信回路电参数获取接口
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_communicat_loop_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    uint32_t leakage_communicate;
    uint32_t leakage_light;
    COMMUNICAT_LOOP_t communicat_loop;
    LIGHT_LOOP_t light_loop;
    CONFIG_CHECK_PARA;
    if(OK != app_control_220v_main_loop_electricity(&communicat_loop))
    {
        return ERROR_COM;
    }
    if(OK != app_control_leakage(&leakage_communicate,&leakage_light))
    {
        return ERROR_COM;
    }
    if(OK != app_control_220v_light_loop_electricity(&light_loop))
    {
        return ERROR_COM;
    }
    PIN_STORE_FLOAT(outdata,communicat_loop.voltage,offset);
    PIN_STORE_FLOAT(outdata,communicat_loop.current,offset);
    PIN_STORE_FLOAT(outdata,communicat_loop.energy,offset);
    PIN_STORE_FLOAT(outdata,communicat_loop.power_value,offset);
    PIN_STORE_FLOAT(outdata,communicat_loop.power_factor,offset);
    PIN_STORE_CHAR(outdata,communicat_loop.loop_status,offset);
    PIN_STORE_LONG(outdata,leakage_communicate,offset);
    PIN_STORE_LONG(outdata,leakage_light,offset);
    PIN_STORE_FLOAT(outdata,light_loop.voltage,offset);
    PIN_STORE_FLOAT(outdata,light_loop.current,offset);
    PIN_STORE_FLOAT(outdata,light_loop.energy,offset);
    PIN_STORE_FLOAT(outdata,light_loop.power_value,offset);
    PIN_STORE_FLOAT(outdata,light_loop.power_factor,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 220V支路电参数获取接口
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_branch_220V_loop_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    BRANCH_220V_LOOP_t branch_220V_loop;
    CONFIG_CHECK_PARA;
    if(OK != app_control_220v_branch_loop_electricity(&branch_220V_loop))
    {
        return ERROR_COM;
    }
    PIN_STORE_FLOAT(outdata,branch_220V_loop.loop_1_current,offset);
    PIN_STORE_FLOAT(outdata,branch_220V_loop.loop_2_current,offset);
    PIN_STORE_FLOAT(outdata,branch_220V_loop.loop_3_current,offset);
    PIN_STORE_FLOAT(outdata,branch_220V_loop.loop_4_current,offset);
    PIN_STORE_FLOAT(outdata,branch_220V_loop.loop_5_current,offset);
    PIN_STORE_CHAR(outdata,branch_220V_loop.loop_1_status,offset);
    PIN_STORE_CHAR(outdata,branch_220V_loop.loop_2_status,offset);
    PIN_STORE_CHAR(outdata,branch_220V_loop.loop_3_status,offset);
    PIN_STORE_CHAR(outdata,branch_220V_loop.loop_4_status,offset);
    PIN_STORE_CHAR(outdata,branch_220V_loop.loop_5_status,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 直流电参数获取接口
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_direct_loop_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    float power_1 = 0;
    float power_2 = 0;
    float power_3 = 0;
    float power_4 = 0;
    float power_5 = 0;
    float power_6 = 0;
    CONFIG_CHECK_PARA;
    DIRECT_ELECTRICITY_t direct_electricity;
    if(OK!= app_control_direct_electricity(&direct_electricity))
    {
        return ERROR_COM;
    }
    PIN_STORE_FLOAT(outdata,direct_electricity.V_12V,offset);
    PIN_STORE_FLOAT(outdata,direct_electricity.V_24V,offset);
    PIN_STORE_FLOAT(outdata,direct_electricity.I_12V_1,offset);
    PIN_STORE_FLOAT(outdata,direct_electricity.I_12V_2,offset);
    PIN_STORE_FLOAT(outdata,direct_electricity.I_12V_3,offset);
    PIN_STORE_FLOAT(outdata,direct_electricity.I_485_VCC1,offset);
    PIN_STORE_FLOAT(outdata,direct_electricity.I_485_VCC2,offset);
    PIN_STORE_FLOAT(outdata,direct_electricity.I_24V,offset);
    power_1 = direct_electricity.I_12V_1*direct_electricity.V_12V;
    power_2 = direct_electricity.I_12V_2*direct_electricity.V_12V;
    power_3 = direct_electricity.I_12V_3*direct_electricity.V_12V;
    power_4 = direct_electricity.I_485_VCC1*direct_electricity.V_12V;
    power_5 = direct_electricity.I_485_VCC2*direct_electricity.V_12V;
    power_6 = direct_electricity.I_24V*direct_electricity.V_24V;
    PIN_STORE_FLOAT(outdata,power_1,offset);
    PIN_STORE_FLOAT(outdata,power_2,offset);
    PIN_STORE_FLOAT(outdata,power_3,offset);
    PIN_STORE_FLOAT(outdata,power_4,offset);
    PIN_STORE_FLOAT(outdata,power_5,offset);
    PIN_STORE_FLOAT(outdata,power_6,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 设备电流最大最小值获取接口
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_dev_current_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t item = 0;
    uint8_t i = 0;
    uint16_t offset = 1;
    float max_current = 0;
    float min_current = 0;
    CONFIG_CHECK_PARA;
    for( i = 0 ; i < AISLE_220V_5 ; i++)
    {
        if(OK == app_control_dev_current_get(i + 1 ,&max_current,&min_current))
        {
            item++;
            PIN_STORE_CHAR(outdata,i+1,offset);
            PIN_STORE_FLOAT(outdata,max_current,offset);
            PIN_STORE_FLOAT(outdata,min_current,offset);
        }
    }
    PIN_CHAR(outdata,item);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 设备连接状态获取接口
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_dev_status_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{  
    CONFIG_CHECK_PARA;
    uint8_t i = 0;
    uint8_t dev_alarm = 0;
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    offset+=1;

    if(OK != Alarm_Assign_State_Get(ALARM_DC24_BREAK,&dev_alarm))
    {
        return ERROR_COM;
    }
    i++;
    PIN_STORE_CHAR(outdata,i,offset);
    PIN_STORE_CHAR(outdata,!dev_alarm,offset);

    if(OK != Alarm_Assign_State_Get(ALARM_DC12_BRANCH1_BREAK,&dev_alarm))
    {
        return ERROR_COM;
    }
    i++;
    PIN_STORE_CHAR(outdata,i,offset);
    PIN_STORE_CHAR(outdata,!dev_alarm,offset);

    if(OK != Alarm_Assign_State_Get(ALARM_DC12_BRANCH2_BREAK,&dev_alarm))
    {
        return ERROR_COM;
    }
    i++;
    PIN_STORE_CHAR(outdata,i,offset);
    PIN_STORE_CHAR(outdata,!dev_alarm,offset);

    if(OK != Alarm_Assign_State_Get(ALARM_DC12_BRANCH3_BREAK,&dev_alarm))
    {
        return ERROR_COM;
    }
    i++;
    PIN_STORE_CHAR(outdata,i,offset);
    PIN_STORE_CHAR(outdata,!dev_alarm,offset);

    if(OK != Alarm_Assign_State_Get(ALARM_UP_DC12V_BREAK,&dev_alarm))
    {
        return ERROR_COM;
    }
    i++;
    PIN_STORE_CHAR(outdata,i,offset);
    PIN_STORE_CHAR(outdata,!dev_alarm,offset);

    if(OK != Alarm_Assign_State_Get(ALARM_EXTEND_DC12V_BREAK,&dev_alarm))
    {
        return ERROR_COM;
    }
    i++;
    PIN_STORE_CHAR(outdata,i,offset);
    PIN_STORE_CHAR(outdata,!dev_alarm,offset);

    if(OK != Alarm_Assign_State_Get(ALARM_AC1_BREAK,&dev_alarm))
    {
        return ERROR_COM;
    }
    i++;
    PIN_STORE_CHAR(outdata,i,offset);
    PIN_STORE_CHAR(outdata,!dev_alarm,offset);

    if(OK != Alarm_Assign_State_Get(ALARM_AC2_BREAK,&dev_alarm))
    {
        return ERROR_COM;
    }
    i++;
    PIN_STORE_CHAR(outdata,i,offset);
    PIN_STORE_CHAR(outdata,!dev_alarm,offset);

    if(OK != Alarm_Assign_State_Get(ALARM_AC3_BREAK,&dev_alarm))
    {
        return ERROR_COM;
    }
    i++;
    PIN_STORE_CHAR(outdata,i,offset);
    PIN_STORE_CHAR(outdata,!dev_alarm,offset);

    if(OK != Alarm_Assign_State_Get(ALARM_AC4_BREAK,&dev_alarm))
    {
        return ERROR_COM;
    }
    i++;
    PIN_STORE_CHAR(outdata,i,offset);
    PIN_STORE_CHAR(outdata,!dev_alarm,offset);

    if(OK != Alarm_Assign_State_Get(ALARM_AC5_BREAK,&dev_alarm))
    {
        return ERROR_COM;
    }
    i++;
    PIN_STORE_CHAR(outdata,i,offset);
    PIN_STORE_CHAR(outdata,!dev_alarm,offset);

    PIN_CHAR(outdata,ALTERNATING_LOOP_LEN + DIRECT_LOOP_LEN);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 氛围灯计划配置
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_ambient_plan_set(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    PLAN_VALUES_t plan_values;
    CONFIG_CHECK_PARA;
    POUT_STORE_CHAR(indata,plan_values.ambient_type,offset);
    POUT_STORE_LONG(indata,plan_values.work_time,offset);
    plan_values.plan_type = PLAN_TYPE_AMBIENT;
    if(OK != app_control_plan_add(&plan_values))
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 氛围灯计划查询
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_ambient_plan_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint8_t i = 0;
    uint8_t item = 0;
    uint16_t offset = 0;
    PLAN_VALUES_t plan_values;
    CONFIG_CHECK_PARA;
    offset+=1;
    for( i = 0 ; i < AMBIENT_PLAN_MAX_NUM ; i++)
    {
        if(OK != app_control_plan_sel(i+LIGHT_PLAN_MAX_NUM,&plan_values))
        {
            return ERROR_COM;
        }
        if(plan_values.plan_type != PLAN_TYPE_NULL)
        {
            PIN_STORE_CHAR(outdata,i + 1 + LIGHT_PLAN_MAX_NUM,offset);
            PIN_STORE_CHAR(outdata,plan_values.ambient_type,offset);
            PIN_STORE_LONG(outdata,plan_values.work_time,offset);
            item++;
        }
    }
    PIN_CHAR(outdata,item);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 重置通信回路电量计量
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_energy_reset(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    if(OK != app_control_energy_reset())
    {
        return ERROR_COM;
    }
    if(OK != app_control_save())
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 时钟查询接口
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_clock_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    uint32_t clock_time;
    rtc_time_t rtc_time;
    CONFIG_CHECK_PARA;
    if(OK != RtcGet(&rtc_time))
    {
        return ERROR_COM;
    }
    extern  uint32_t my_mktime( rtc_time_t *tm );
    clock_time = my_mktime(&rtc_time);
    clock_time-=8*60*60;
    PIN_STORE_LONG(outdata,clock_time,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 单灯功率查询接口
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_light_power_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    CONFIG_CHECK_PARA;
    BRANCH_220V_LOOP_t branch_220V_loop;
    if(OK != app_control_220v_branch_loop_electricity(&branch_220V_loop))
    {
        return ERROR_COM;
    }
    PIN_STORE_FLOAT(outdata,branch_220V_loop.light1_power,offset);
    PIN_STORE_FLOAT(outdata,branch_220V_loop.light2_power,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 查询倾斜传感器数值
 * @param src               数据包头
 * @param indata            输入报文
 * @param indata_len        输入报文长度
 * @param outdata           输出报文
 * @param outdata_len       输出报文长度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_config_tilt_data_get(uint8 *src, uint8_t * indata,uint16_t indata_len,uint8_t * outdata,uint16_t *outdata_len)
{
    uint16_t offset = 0;
    int32_t error_code;
    float tilt_x = 0;
    float tilt_y = 0;
    float tilt_z = 0;
    CONFIG_CHECK_PARA;
    error_code = app_control_tilt(&tilt_x,&tilt_y,&tilt_z);
    if(OK != error_code)
    {
        return ERROR_COM;
    }
    PIN_STORE_FLOAT(outdata,tilt_x,offset);
    PIN_STORE_FLOAT(outdata,tilt_y,offset);
    PIN_STORE_FLOAT(outdata,tilt_z,offset);
    *outdata_len = offset;
    return OK;
}

/**
 * @brief 设备配置模块初始化
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
uint8_t app_config_init(void)
{
    Msc_Cmd_Reg(CMD_SET_DEVICE,app_config_info_set);
    Msc_Cmd_Reg(CMD_GET_DEVICE,app_config_info_get);
    Msc_Cmd_Reg(CMD_SET_NET,app_config_net_set);
    Msc_Cmd_Reg(CMD_GET_NET,app_config_net_get);
    Msc_Cmd_Reg(CMD_SET_RS485,app_config_485_set);
    Msc_Cmd_Reg(CMD_GET_RS485,app_config_485_get);
    Msc_Cmd_Reg(CMD_SET_PORT_MAP,app_config_mapping_set);
    Msc_Cmd_Reg(CMD_GET_PORT_MAP,app_config_mapping_get);
    Msc_Cmd_Reg(CMD_SET_POWER,app_config_switch_set);
    Msc_Cmd_Reg(CMD_GET_POWER,app_config_switch_get);
    Msc_Cmd_Reg(CMD_SET_SINGER_LAMP,app_config_single_light_brightness_set);
    Msc_Cmd_Reg(CMD_GET_SINGER_LAMP,app_config_single_light_brightness_get);
    Msc_Cmd_Reg(CMD_SET_SINGER_LAMP_PLAN,app_config_light_plan_set);
    Msc_Cmd_Reg(CMD_GET_SINGER_LAMP_PLAN,app_config_light_plan_get);
    Msc_Cmd_Reg(CMD_SET_DELETE_SINGLE_LAMP,app_config_light_plan_del);
    Msc_Cmd_Reg(CMD_SET_ATMO_LAMP_TYPE,app_config_ambient_set);
    Msc_Cmd_Reg(CMD_GET_ATMO_LAMP_TYPE,app_config_ambient_get);
    Msc_Cmd_Reg(CMD_SET_TEMPHUM,app_config_temperature_threshold_set);
    Msc_Cmd_Reg(CMD_GET_TEMPHUM,app_config_temperature_threshold_get);
    Msc_Cmd_Reg(CMD_SET_LEAN,app_config_tilt_threshold_set);
    Msc_Cmd_Reg(CMD_GET_LEAN,app_config_tilt_threshold_get);
    Msc_Cmd_Reg(CMD_SET_HEART_CYCLE,app_config_heart_set);
    Msc_Cmd_Reg(CMD_GET_HEART_CYCLE,app_config_heart_get);
    Msc_Cmd_Reg(CMD_GET_SOFTHARD_VERSION,app_config_version_get);
    Msc_Cmd_Reg(CMD_SET_TEMPLEAKAGE_ACTION,app_config_temperature_leakage_enable_set);
    Msc_Cmd_Reg(CMD_GET_TEMPLEAKAGE_ACTION,app_config_temperature_leakage_enable_get);
    Msc_Cmd_Reg(CMD_SET_FANHEATER,app_config_fan_heater_threshold_set);
    Msc_Cmd_Reg(CMD_GET_FANHEATER,app_config_fan_heater_threshold_get);
    Msc_Cmd_Reg(CMD_SET_DI_STATE,app_config_di_set);
    Msc_Cmd_Reg(CMD_GET_DI_STATE,app_config_di_get);
    Msc_Cmd_Reg(CMD_SET_PLATFORM,app_config_north_connect_set);
    Msc_Cmd_Reg(CMD_GET_PLATFORM,app_config_north_connect_get);
    Msc_Cmd_Reg(CMD_SET_LEAKAGE_TIMES,app_config_leakage_threshold_set);
    Msc_Cmd_Reg(CMD_GET_LEAKAGE_TIMES,app_config_leakage_threshold_get);
    Msc_Cmd_Reg(CMD_GET_LEAN_ORI_VALUE,app_config_tilt_get);
    Msc_Cmd_Reg(CMD_SET_TIME,app_config_clock_set);
    Msc_Cmd_Reg(CMD_GET_MSC_LOOP,app_config_communicat_loop_get);
    Msc_Cmd_Reg(CMD_GET_AC_BRANCH,app_config_branch_220V_loop_get);
    Msc_Cmd_Reg(CMD_GET_DC_BRANCH,app_config_direct_loop_get);
    Msc_Cmd_Reg(CMD_GET_MINMAX_A,app_config_dev_current_get);
    Msc_Cmd_Reg(CMD_GET_DEVICE_STATE,app_config_dev_status_get);
    Msc_Cmd_Reg(CMD_SET_LAMP_PLAN,app_config_ambient_plan_set);
    Msc_Cmd_Reg(CMD_GET_LAMP_PLAN,app_config_ambient_plan_get);
    Msc_Cmd_Reg(CMD_ENERGY_RESET,app_config_energy_reset);
    Msc_Cmd_Reg(CMD_GET_TIME,app_config_clock_get);
    Msc_Cmd_Reg(CMD_GET_LIGHT_POWER,app_config_light_power_get);
	Msc_Cmd_Reg(CMD_GET_TILT_DATA,app_config_tilt_data_get);
    return OK;
}

#endif /* BOARD_PCU_EN */
